package com.yulinlin.jdbc.mysql;

import com.yulinlin.core.wrapper.*;

import java.util.HashMap;
import java.util.Map;

public class MysqlSelectWrapper<E,R> implements ISelectWrapper<E,R> {

    private IColumnWrapper<ISelectWrapper<E, R>> columnWrapper;

    private IStringConditionWrapper<E,ISelectWrapper<E,R>> whereWrapper;

    private IStringConditionWrapper<E,ISelectWrapper<E,R>> havingWrapper;

    private ITableWrapper<E, ISelectWrapper<E, R>> tableWrapper;

    private IParamsWrapper params;

    //分组
    private StringBuffer groupSql;

    //排序
    private StringBuffer orderSql;

    //默认分页15
    private int pageNumber = -1;

    private int pageSize = 15;

    private  boolean isLock = false;

    private R endWrapper;



    public MysqlSelectWrapper(R endWrapper) {

        this.endWrapper = endWrapper;
        this.params = new MysqlParamsWrapper();
        this.tableWrapper = new MysqlTableWrapper(this,params);
        this.columnWrapper = new MysqlColumnWrapper(this,params);
        this.whereWrapper = new MysqlStringConditionWrapper(this,params);
        this.havingWrapper = new MysqlStringConditionWrapper(this,params,false);
        this.groupSql = new StringBuffer();
        this.orderSql = new StringBuffer();


    }

    @Override
    public IColumnWrapper<ISelectWrapper<E, R>> data() {
        return columnWrapper;
    }

    @Override
    public ITableWrapper<E, ISelectWrapper<E, R>> from() {
        return tableWrapper;
    }

    @Override
    public IStringConditionWrapper<E, ISelectWrapper<E, R>> where() {
        return whereWrapper;
    }

    @Override
    public IStringConditionWrapper<E, ISelectWrapper<E, R>> having() {
        return havingWrapper;
    }

    @Override
    public ISelectWrapper<E,R> group(String name) {
        if(groupSql.length() > 0){
            groupSql.append(" , ");
        }
        groupSql.append(name);
        return this;
    }

    private ISelectWrapper<E,R> order(String name ,boolean order){
        if(orderSql.length() > 0){
            orderSql.append(" , ");
        }
        orderSql.append(name);
        if(order){
            orderSql.append(" asc ");

        }else{
            orderSql.append(" desc ");
        }
        return  this;
    }

    @Override
    public ISelectWrapper<E,R> orderByAsc(String name) {
        return order(name,true);
    }

    @Override
    public ISelectWrapper<E,R> orderByDesc(String name) {
        return order(name,false);
    }

    @Override
    public ISelectWrapper<E,R> limit(int pageNumber, int pageSize) {
        this.pageNumber = pageNumber;
        this.pageSize = pageSize;
        return this;
    }

    @Override
    public ISelectWrapper<E, R> lock() {
        this.isLock = true;
        return this;
    }

    @Override
    public String getSql() {
        StringBuffer sb =  new StringBuffer("select ");


        sb.append(columnWrapper.getSql());

        sb.append(" from ");

        sb.append(tableWrapper.getSql());

        String whereSql =  whereWrapper.getSql();
        if(whereSql.length() > 0){
            sb.append(" where "+whereSql);
        }
        String havingSql =  havingWrapper.getSql();
        if(havingSql.length() > 0){
            sb.append(" having "+havingSql);
        }

        if(groupSql.length() > 0){
            sb.append(" group by "+ groupSql);
        }
        if(orderSql.length() > 0){
            sb.append(" order by "+ orderSql);
        }


        if(this.pageNumber > 0){
            int offset = (this.pageNumber - 1) * this.pageSize;
            sb.append(" limit "+offset+" , "+this.pageSize);
        }

        if(isLock){
            sb.append(" for update ");
        }

        return sb.toString();
    }

    @Override
    public R end() {
        return endWrapper;
    }

    @Override
    public IParamsWrapper getParams() {
        return params;
    }
}
